import os, glob, sys, re
import shlex
import adprops

class ArduinoConfig:
    compilerPaths = {'sam' : 'g++_arm_none_eabi/bin', 'avr' : 'g++_arm_none_eabi/bin' }
    compilerPrefixes = {'avr' : 'avr-', 'sam' : 'arm-none-eabi-' }
    def __init__(self, arch = 'sam', variant = 'arduino_due_x'):
        self.arch = arch
        self.variant = variant
        self.basePath = None
        ardPaths = []
        vre = re.compile('arduino-([0-9]).([0-9]).([0-9])')
        # self.extractIncludesRE = re.compile('\"-I(.+?)\"')
        for base in ['/usr/local', '/usr/share' '/usr/local/share' ]:
            ardPaths += glob.glob(os.path.join(base, 'arduino*'))
        if ardPaths:
            highestVersionSeen = -1
            for fname in ardPaths:
                if os.path.isdir(fname):
                    spl =  os.path.split(fname)
                    vmatch = vre.match(spl[1])
                    if vmatch:
                        numberVersion = int(vmatch.group(1)) * 100 * 100 + int(vmatch.group(2)) * 100 + int(vmatch.group(3))
                        if numberVersion > highestVersionSeen:
                            highestVersionSeen = numberVersion
                            self.basePath = fname
        if not self.basePath:
            print("no arduino basepath found, exception")
            sys.exit(1)

        self.hardwarePath = os.path.join(self.basePath, 'hardware')
        self.arduinoPath = os.path.join(self.hardwarePath, 'arduino')
        self.toolsPath = os.path.join(self.basePath, 'tools')
        self.compilerPath = os.path.join(self.toolsPath, self.compilerPaths[arch])
        self.compilerPrefix = self.compilerPrefixes[arch]
        self.archPath = os.path.join(os.path.join(self.arduinoPath, arch))
        self.systemPath = os.path.join(os.path.join(self.archPath, 'system'))

        self.configProps = adprops.adprops(os.path.join(self.archPath, 'boards.txt'))
        self.configProps.LoadFile(os.path.join(self.archPath, 'platform.txt'))
        # substitute these paths directly into the java properties file
        self.configProps['build.system.path'] = self.systemPath
        self.configProps['runtime.ide.path'] = self.basePath
        self.configProps.PropsSubstituteAll()
        # extract out the variant from the boards files and substitute them
        self.configProps.PropsSubstituteAll(fromPrefix = variant)
        for key in sorted(self.configProps.keys()):
            print key, "=", self.configProps[key]

    def ConvertLibNameForMinusL(self, nameIn):
        return nameIn[3:-2]

    def LoadTools(self, ctx):
        # executables
        for aval, wval in [('CXX', 'cpp'), ('CC', 'c'), ('AR', 'ar'),  ('SIZE', 'size'), ('OBJCOPY', 'objcopy'), ('LD', 'ld')]:
            ctx.env[aval] = os.path.join(self.configProps['compiler.path'], self.configProps['compiler.' + wval + '.cmd'])
        # defines


#        ctx.env['INCLUDES'] = self.extractIncludesRE.findall(self.configProps['compiler.libsam.c.flags'])
        ctx.env.append_value('CFLAGS', shlex.split(self.configProps['compiler.c.flags']))
        ctx.env.append_value('CXXFLAGS', shlex.split(self.configProps['compiler.cpp.flags']))

        if self.variant + '.build.extra_flags' in self.configProps:
            ctx.env.append_value('CFLAGS', shlex.split(self.configProps['arduino_due_x.build.extra_flags']))
            ctx.env.append_value('CXXFLAGS', shlex.split(self.configProps['arduino_due_x.build.extra_flags']))

        ctx.env.append_value('DEFINES', 'F_CPU=' +  self.configProps[self.variant + '.build.f_cpu'])
        ctx.env.append_value('DEFINES', 'ARDUINO=152')
        ctx.env.append_value('CFLAGS', '-mcpu=' + self.configProps[self.variant + '.build.mcu'])
        ctx.env.append_value('CXXFLAGS', '-mcpu=' + self.configProps[self.variant + '.build.mcu'])
        ctx.env.append_value('LINKFLAGS', '-mcpu=' + self.configProps[self.variant + '.build.mcu'])

        ctx.env.append_value('INCLUDES', os.path.join(self.arduinoPath, self.arch, 'variants', self.variant))
        if self.arch == 'sam':
            ctx.env.append_value('CXXFLAGS', shlex.split(self.configProps['compiler.libsam.c.flags']))
            ctx.env.append_value('CFLAGS', shlex.split(self.configProps['compiler.libsam.c.flags']))
            # Convert into a normal -l library name, maybe do this with a regex?
            print "LIBASAM flags", shlex.split(self.configProps['compiler.libsam.c.flags'])
            ctx.env.append_value('LINKFLAGS', ['-Wl,--gc-sections'])
            ctx.env.append_value('LINKFLAGS', ['-Wl,--entry=Reset_Handler'])
            ctx.env.append_value('LINKFLAGS', ['-Wl,--check-sections', '-Wl,--unresolved-symbols=report-all', '-Wl,--warn-common', '-Wl,--warn-section-align'])
            #                                               '-Wl,--warn-unresolved-symbols'])
            ctx.env.append_value('CRT', os.path.join(self.arduinoPath, self.arch, 'variants',
                    self.variant, self.configProps[self.variant + '.build.variant_system_lib']))
            ctx.env.append_value('LIB', 'gcc')
            ctx.env.append_value('LINKFLAGS', '-T' + os.path.join(self.arduinoPath, self.arch, 'variants', self.variant,
                            self.configProps[self.variant + '.build.ldscript']))




